/**
 * edurender
 * ersw_vertex.c
 * (c) 2009 J. Brad Byrd
 */

#include "ersw_vertex.h"

#include "../er/er_math.h"

#include <string.h>

void erswTransformVertices(const ERSWVertexState *state,
	const ERSWInputVertex *input, ERSWOutputVertex *output, ERuint count)
{
	ERushort i;	
	ERMatrix4x4f pmv;
	ERfloat xscale = state->viewport.width * 0.5f;
	ERfloat xbias = (float)state->viewport.x;
	ERfloat yscale = state->viewport.height * 0.5f;
	ERfloat ybias = (float)state->viewport.y;
	ERfloat zscale = 0.5f;
	ERfloat zbias = 0.0f;
	const ERSWInputVertex *src = input;
	ERSWOutputVertex *dst = output;

	erMulMatrix(&pmv, &state->projection, &state->modelview);
	
	for (i = 0; i < count; i++)
	{	
		ERfloat iw;
		
		erTransformPoint3(&dst->hpos, &pmv, &src->position);
		
		dst->clip  = (dst->hpos.x < -dst->hpos.w);
		dst->clip |= (dst->hpos.x >  dst->hpos.w) << 1;
		dst->clip |= (dst->hpos.y < -dst->hpos.w) << 2;
		dst->clip |= (dst->hpos.y >  dst->hpos.w) << 3;
		dst->clip |= (dst->hpos.z < -dst->hpos.w) << 4;
		dst->clip |= (dst->hpos.z >  dst->hpos.w) << 5;
		
		iw = 1.0f / dst->hpos.w;
		
		dst->spos.x = ((dst->hpos.x * iw) + 1.0f) * xscale + xbias;
		dst->spos.y = ((dst->hpos.y * iw) + 1.0f) * yscale + ybias;
		dst->spos.z = ((dst->hpos.z * iw) + 1.0f) * zscale + zbias;
		
		// JBB_TODO: Texture matrix.
		dst->texCoord[0].x = src->texCoord[0].x * iw;
		dst->texCoord[0].y = src->texCoord[0].y * iw;
		
		dst->invW = iw;
		
		src++;
		dst++;
	}
}
